package wortubung.lang;

import java.util.ArrayList;
import java.util.Arrays;

import wortubung.Messages;
import wortubung.WortUbung;
import wortubung.core.MEANING;
import wortubung.core.WORD;
import wortubung.util.CommonUtils;
import wortubung.wordlist.WordListInfo;

@SuppressWarnings("serial")
public class WordCollection extends ArrayList<WORD> {

    private int maxWordLen = 5;
	private boolean allSameSpelling = true;
	private LanguageManager langManager;

	public WordCollection(LanguageManager langManager) {
    	this.langManager = langManager;
    }

	public WortUbung getDictionary() {
		return langManager.getWortUbung();
	}

	@Override
	public void clear() {
		super.clear();
		maxWordLen = 5;
		allSameSpelling = true;
	}

	@Override
	public boolean add(WORD word) {
		if (word.getWord().length() > maxWordLen)
			maxWordLen = word.getWord().length();
		if (allSameSpelling) {
    		for (WORD wd : this) {
    			if (!wd.getWord().equals(word.getWord())) {
    				allSameSpelling = false;
    				break;
    			}
    		}
		}
		return super.add(word);
	}

	public WordCollection find(String regex) {
    	for (WORD word : langManager.getWords()) {
    		try {
    			if (word.getAnglicizedWord().matches(regex))
        			add(word);
    		} catch(Exception e) {}
    	}
    	return this;
	}

	public void findAndShowWords(String regex) {
		find(regex);
    	if (isEmpty())
    		langManager.promptln(Messages.WORD_NOT_FOUND, regex);
   		else
   			show(true);
	}

	public void findAndShowWordsByDescription(String regex) {
    	for (WORD word : langManager.getWords()) {
    		if (word.searchFirstDefinition(regex))
    			add(word);
    	}
    	if (isEmpty())
    		langManager.promptln(Messages.WORD_NOT_FOUND_FOR_DESC, regex);
    	else
    		show(true);
	}

	public void findAndShowWordLists(String params) {
    	for (WordListInfo wl : langManager.getWordLists(params))
        	for (WORD word : wl.getWords())
       			add(word);
    	if (isEmpty())
    		langManager.promptln(Messages.WORD_LISTS_NOT_FOUND, params);
    	else
    		show(false);
	}

	private void show(boolean sort) {
    	int width = maxWordLen + 2;
    	if (allSameSpelling) {
    		WORD word = null;
        	for (WORD wd : this) {
        		word = wd;
        		for (String line : word.toCompleteInfoDisplay(getDictionary().getPageWidth(), false))
        			println(line);
       			println();
        	}
        	if (word != null)
        		langManager.addLatestWord(word.getWord());
    	} else {
    		String fmt = "%" + CommonUtils.numDigits(size()) + "d. ";
    		int idx = 0;
    		WORD[] words = toArray(new WORD[size()]);
    		boolean isSingleWord = (words.length == 1);
    		if (sort)
    			Arrays.sort(words);
        	for (WORD word : words) {
        		MEANING m = null;
        		if (word.getTemp() instanceof MEANING)
        			m = (MEANING)word.getTemp();
        		for (String line : word.toQuickLine(0, String.format(fmt, ++idx), width, getDictionary().getPageWidth(), m, false))
            		println(CommonUtils.makeStringLen(line, 0, getDictionary().getPageWidth(), ' ') + ':');
            	if (isSingleWord)
            		langManager.addLatestWord(word.getWord());
        	}
        	println();
    	}
	}

    private void println(String msg) { getDictionary().println(msg); }
    private void println() { getDictionary().println(); }
}
